//
//  ViewController.m
//  3.24、GCD
//
//  Created by 李坤 on 16/12/14.
//
//

#import "ViewController.h"
#import "Demo.h"
@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    [NSThread currentThread].name = @"我是主线程";
    
    NSLog(@"--------start");
    [self t14];
    NSLog(@"--------end");
    
//    UILabel *lab = [[UILabel alloc] init];
//    lab.frame = CGRectMake(50, 100, self.view.bounds.size.width-100, 30);
//    lab.backgroundColor = [UIColor redColor];
//    lab.textColor = [UIColor whiteColor];
//    lab.text = @"GCD";
//    [self.view addSubview:lab];
//    [NSThread sleepForTimeInterval:2];
//    [UIView beginAnimations:nil context:nil];
//    [UIView setAnimationDuration:3];
//    lab.frame = CGRectMake(100, 100, self.view.bounds.size.width-200, 300);
    
    [UIView commitAnimations];
}

//并行执行多个任务，待多个任务执行完毕之后，在执行其他任务
- (void)t14{
    NSLog(@"%@---start",[NSThread currentThread]);
    dispatch_group_t group = dispatch_group_create();
    dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
//    queue = dispatch_queue_create("queue1", NULL);
    dispatch_group_async(group, queue, ^{
        NSString *name = @"task1";
        NSLog(@"%@---%@star",[NSThread currentThread],name);
        for (int i = 0; i<5; i++) {
            [NSThread sleepForTimeInterval:i*0.01];
            NSLog(@"%@---%@---%i",[NSThread currentThread],name,i);
        }
        NSLog(@"%@---%@end",[NSThread currentThread],name);
    });
    dispatch_group_async(group, queue, ^{
        NSString *name = @"task2";
        NSLog(@"%@---%@star",[NSThread currentThread],name);
        for (int i = 0; i<5; i++) {
            [NSThread sleepForTimeInterval:i*0.01];
            NSLog(@"%@---%@---%i",[NSThread currentThread],name,i);
        }
        NSLog(@"%@---%@end",[NSThread currentThread],name);
    });
    NSLog(@"%@---in",[NSThread currentThread]);
    dispatch_group_notify(group, dispatch_get_main_queue(), ^{
        NSString *name = @"task3";
        NSLog(@"%@---%@star",[NSThread currentThread],name);
        for (int i = 0; i<5; i++) {
            [NSThread sleepForTimeInterval:i*0.01];
            NSLog(@"%@---%@---%i",[NSThread currentThread],name,i);
        }
        NSLog(@"%@---%@end",[NSThread currentThread],name);
    });
    NSLog(@"%@---end",[NSThread currentThread]);
}


- (void)t13{
    //调用t13_in:withAge:方法 ，方式1
    [self performSelector:@selector(t13_in:withAge:) withObject:@"ready" withObject:@12];
    
    //方式2
    SEL sel = @selector(t13_in:withAge:);
    IMP imp = [self methodForSelector:sel];
    void (*func)(id,SEL,NSString *,NSNumber *) = (void *)imp;
    NSLog(@"%p",func);
    func(self,sel,@"tom",@18);
    
    
}

- (void)t13_in:(NSString *)name withAge:(NSNumber *)age{
    
    NSLog(@"我是通过IML调用方式被调用的，name = %@,age = %i",name,age.intValue);
}

- (void)t12{
    [[[Demo alloc] init] once:self withSel:@selector(t12_m1)];
}

- (void)t12_m1{
    
    NSLog(@"只执行一次,%@",[NSThread currentThread]);
}

//延迟执行，使用GCD中的方法
- (void)t11{
    dispatch_after(2*NSEC_PER_SEC, dispatch_queue_create("xxx", NULL), ^{
        [self m1];
    });
}

//延迟执行，使用NSObject的方法，只能放在主线程中执行
- (void)t10{
    [self performSelector:@selector(m1) withObject:NULL afterDelay:1];
}

- (void)t9{
    NSLog(@"0----%@",[NSThread currentThread]);
    dispatch_queue_t queue = dispatch_queue_create("queue", NULL);
    dispatch_async(queue, ^{
        NSLog(@"3----%@",[NSThread currentThread]);
//        [self performSelectorOnMainThread:@selector(m1) withObject:NULL waitUntilDone:NO];
        dispatch_async(dispatch_get_main_queue(), ^{
            [self m1];
        });
        NSLog(@"4----%@",[NSThread currentThread]);

    });
    NSLog(@"1----%@",[NSThread currentThread]);

}

- (void)t8{
    NSLog(@"0----%@",[NSThread currentThread]);
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
//    dispatch_queue_t queue = dispatch_queue_create("queue1", NULL);
    
    dispatch_async(queue, ^{
        NSLog(@"2----%@",[NSThread currentThread]);
        dispatch_async(queue, ^{
            NSString *name = @"block1";
            for (int i=0; i<5; i++) {
                NSLog(@"%@---%@---%i",name,[NSThread currentThread],i);
            }
        });
        dispatch_async(queue, ^{
            NSString *name = @"block2";
            for (int i=0; i<5; i++) {
                NSLog(@"%@---%@---%i",name,[NSThread currentThread],i);
            }
        });
        dispatch_async(queue, ^{
            NSString *name = @"block3";
            for (int i=0; i<5; i++) {
                NSLog(@"%@---%@---%i",name,[NSThread currentThread],i);
            }
        });
        NSLog(@"3----%@",[NSThread currentThread]);
    });
    NSLog(@"1----%@",[NSThread currentThread]);
}

- (void)t7{
    NSLog(@"0----%@",[NSThread currentThread]);
    //创建一个串行对垒
    dispatch_queue_t queue = dispatch_queue_create("queue", DISPATCH_QUEUE_SERIAL);
    
    //异步执行
    dispatch_async(queue, ^{//block1开始
        NSLog(@"1----%@",[NSThread currentThread]);//子线程打印
        
        dispatch_async(queue, ^{//block2开始
            [NSThread sleepForTimeInterval:2];
            NSLog(@"2----%@",[NSThread currentThread]);
        });//block2结束
        
        
        NSLog(@"3----%@",[NSThread currentThread]);
        
        dispatch_async(queue, ^{//block3开始
            NSLog(@"4----%@",[NSThread currentThread]);
        });//block3结束
        
        NSLog(@"5----%@",[NSThread currentThread]);
    });//block1结束
    NSLog(@"6----%@",[NSThread currentThread]);
}

/*
 手动创建串行队列，同步执行任务
 会在当前线程中执行，会阻塞当前线程
 */
- (void)t1{
    NSLog(@"主线程:%@",[NSThread mainThread]);
    dispatch_queue_t dq1 = dispatch_queue_create("dq1", NULL);
    dispatch_sync(dq1, ^{
        [self call:@"task1"];
    });
    dispatch_sync(dq1, ^{
        [self call:@"task2"];
    });
    dispatch_sync(dq1, ^{
        [self call:@"task3"];
    });
}

/*
 手动创建串行队列，异步执行，不会阻塞当前线程
 会创建一个新的线程，多个任务会在这个线程中按顺序执行
*/
- (void)t2{
    NSLog(@"主线程:%@",[NSThread mainThread]);
    dispatch_queue_t dq1 = dispatch_queue_create("dq1", NULL);
    dispatch_async(dq1, ^{
        [self call:@"task1"];
    });
    dispatch_async(dq1, ^{
        [self call:@"task2"];
    });
    dispatch_async(dq1, ^{
        [self call:@"task3"];
    });
}

/*
 使用主队列，主队列是系统默认的一个串行队列，同步执行
 放在主队列中的任务都会放在主线程中执行，不会创建新的线程，会阻塞当前线程，在主线程中使用同步方法向主队列中添加任务会导致死锁.
 注意下面的t3方法不能放在主线程中执行
 */
- (void)t3{
    NSLog(@"主线程:%@",[NSThread mainThread]);
    dispatch_queue_t dq1 = dispatch_get_main_queue();
    dispatch_sync(dq1, ^{
        [self call:@"task1"];
    });
    dispatch_sync(dq1, ^{
        [self call:@"task2"];
    });
    dispatch_sync(dq1, ^{
        [self call:@"task3xxx"];
    });
}

/*
 使用主队列，主队列是系统默认的一个串行队列，同步执行
 放在主队列中的任务都会放在主线程中执行，不会创建新的线程，不会阻塞当前线程
 */
- (void)t4{
    NSLog(@"主线程:%@",[NSThread mainThread]);
    dispatch_queue_t dq1 = dispatch_get_main_queue();
    //注意此处只能异步执行
    dispatch_async(dq1, ^{
        [self call:@"task1"];
    });
    dispatch_async(dq1, ^{
        [self call:@"task2"];
    });
    dispatch_async(dq1, ^{
        [self call:@"task3xxx"];
    });
}
/*
 使用全局并发队列，同步执行
 会在当前线程中执行，会阻塞当前队列，多个任务会串行执行
 */
- (void)t5{
    dispatch_queue_t dq1 = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    dispatch_sync(dq1, ^{
        [self call:@"task1"];
    });
    dispatch_sync(dq1, ^{
        [self call:@"task2"];
    });
    dispatch_sync(dq1, ^{
        [self call:@"task3"];
    });
}

/*
 使用全局并发队列，异步执行
 会创建多个新的线程，任务不会阻塞当前线程，多个任务会并行执行
 */
- (void)t6{
    dispatch_queue_t dq1 = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    dispatch_async(dq1, ^{
        [self call:@"task1"];
    });
    dispatch_async(dq1, ^{
        [self call:@"task2"];
    });
    dispatch_async(dq1, ^{
        [self call:@"task1"];
    });
}

- (void)call:(NSString *)str{

    NSLog(@"%@----%@----start",str,[NSThread currentThread]);
    [NSThread sleepForTimeInterval:1];
    NSLog(@"%@----%@----end",str,[NSThread currentThread]);

}


- (void)tx{
    //1.获得全局的并发队列
    dispatch_queue_t queue =  dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    //2.添加任务到队列中，就可以执行任务
    //异步函数：具备开启新线程的能力
    dispatch_async(queue, ^{
        [NSThread sleepForTimeInterval:1];
        NSLog(@"下载图片1----%@",[NSThread currentThread]);
    });
    dispatch_async(queue, ^{
        NSLog(@"下载图片2----%@",[NSThread currentThread]);
    });
    dispatch_async(queue, ^{
        NSLog(@"下载图片2----%@",[NSThread currentThread]);
    });
    //打印主线程
    NSLog(@"主线程----%@",[NSThread mainThread]);
}

- (void)m3{
    //串行队列
    dispatch_queue_t dispatch = dispatch_queue_create("dq1", NULL);
//    dispatch_queue_t dispatch = dispatch_get_main_queue();
    dispatch_async(dispatch, ^{
//        [NSThread currentThread].name = @"子线程1";
        [self m1];
    });
    dispatch_async(dispatch, ^{
        
        [self m1];
    });
}

- (void)m2{
    //串行队列
    dispatch_queue_t dispatch = dispatch_queue_create("dq1", NULL);
    dispatch_sync(dispatch, ^{
        [self m1];
    });dispatch_sync(dispatch, ^{
        [self m1];
    });
    
    NSLog(@"%@",dispatch);
    NSLog(@"%@",dispatch_queue_create("dq1", NULL));
    NSLog(@"%@",dispatch_get_main_queue());
    
    [NSThread detachNewThreadWithBlock:^{
        [NSThread currentThread].name = @"子线程1";
        dispatch_queue_t dispatch2 = dispatch_queue_create("串行队列1", NULL);
        dispatch_sync(dispatch2, ^{
            [self m1];
        });dispatch_sync(dispatch2, ^{
            [self m1];
        });
    }];
    
}

- (void)m1{
    NSLog(@"--------------------------\n\n");
    for(int i = 0;i<10;i++){
        [NSThread sleepForTimeInterval:0.01*i];
        NSLog(@"%@,%i",[NSThread currentThread].name,i);
    }
}


- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}


@end
